package com.mall.order.services;

import com.mall.commons.tool.exception.BizException;
import com.mall.commons.tool.exception.ValidateException;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mall.order.OrderCoreService;
import com.mall.order.biz.TransOutboundInvoker;
import com.mall.order.biz.context.AbsTransHandlerContext;
import com.mall.order.biz.factory.OrderProcessPipelineFactory;
import com.mall.order.constants.OrderConstants;
import com.mall.order.dal.entitys.*;
import com.mall.order.constant.OrderRetCode;
import com.mall.order.converter.OrderConverter;
import com.mall.order.dal.persistence.*;
import com.mall.order.dto.*;
import com.mall.shopping.constants.ShoppingRetCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * cskaoyan
 * create-date: 2019/7/30-上午10:05
 */
@Slf4j
@Component
@Service(cluster = "failfast") //TODO 可以考虑设置集群
public class OrderCoreServiceImpl implements OrderCoreService {

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    OrderItemMapper orderItemMapper;

    @Autowired
    OrderShippingMapper orderShippingMapper;

    @Autowired
    OrderProcessPipelineFactory orderProcessPipelineFactory;


    @Autowired
    StockMapper stockMapper;

    //获取商品的详细信息
    @Autowired
	ItemMapper itemMapper;

    @Autowired
	PromoSessionMapper promoSessionMapper;

    @Autowired
	PromoItemMapper promoItemMapper;


    /**
     * 取消订单的处理流程
     * 在未付款状态，可以执行取消订单操作
     *
     * @param request
     * @return
     */
    @Override
    public CancelOrderResponse cancelOrder(CancelOrderRequest request) {

        CancelOrderResponse response = new CancelOrderResponse();
        try {
            request.requestCheck();
            //1.判断order表status =0 时可取消订单
            Order order = orderMapper.selectByPrimaryKey(request.getOrderId());
            if (order.getStatus() == OrderConstants.ORDER_STATUS_INIT) {
                //1.修改order表status
                order.setStatus(OrderConstants.ORDER_STATUS_TRANSACTION_CANCEL);
                order.setUpdateTime(new Date());
                orderMapper.updateByPrimaryKeySelective(order);
                //2.通过orderItem表查该订单中的所有item
                List<OrderItem> orderItems = orderItemMapper.queryByOrderId(request.getOrderId());
                //3.通过item修改stock表stock_count,lock_count
                for (OrderItem orderItem : orderItems) {
                    //将item表中该订单的所有item的status改为2库存已释放状态
                    orderItemMapper.updateStockStatus(2,request.getOrderId());

                    //判断是否为秒杀商品，如果是秒杀商品将返回秒杀商品的库存
					String sessionId = "1";
					Calendar calendar = Calendar.getInstance();
					int hour = calendar.get(Calendar.HOUR_OF_DAY);
					if (hour >= 16) {
						sessionId = "2";
					}
					String yyyyMMdd = new SimpleDateFormat("yyyyMMdd").format(new Date());
					//通过价格去判断是否为秒杀商品 //TODO 最好用标志位
					Long itemId = orderItem.getItemId();
					Item item = itemMapper.selectByPrimaryKey(itemId);
					double price = orderItem.getPrice();
					double value = item.getPrice().doubleValue();
					if (price < value) {
						//如果价格不相等说明是秒杀商品
						//通过时间和sessionId定位场次-->再通过商品Id和场次找到秒杀详情表，库存+1
						Example example = new Example(PromoSession.class);
						example.createCriteria()
								.andEqualTo("sessionId",sessionId)
								.andEqualTo("yyyymmdd",yyyyMMdd);
						List<PromoSession> promoSessions = promoSessionMapper.selectByExample(example);
						PromoSession promoSession = promoSessions.get(0);
						//获得场次Id和产品Id
						Long psId = promoSession.getId();
						//更新代码库存+1的mapper重写了
						promoItemMapper.increaseStock(itemId,psId);

					} else {
						//通过商品id找到库存
						Stock stock = stockMapper.selectStock(orderItem.getItemId());
						//修改更新库存的库存数量
						stock.setStockCount(orderItem.getNum().longValue());
						stock.setLockCount(-orderItem.getNum());
						stockMapper.updateStock(stock);
					}
                }
                response.setCode(OrderRetCode.SUCCESS.getCode());
                response.setMsg(OrderRetCode.SUCCESS.getMessage());
            }else {
                response.setCode(OrderRetCode.DB_EXCEPTION.getCode());
                response.setMsg(OrderRetCode.DB_EXCEPTION.getMessage());
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.setCode(OrderRetCode.SYSTEM_TIMEOUT.getCode());
            response.setMsg(OrderRetCode.SYSTEM_TIMEOUT.getMessage());
        }

        return response;
    }

    /**
     * 删除订单的处理流程
     * 在订单完成（可成功，可失败）状态，可以执行删除订单操作
     *
     * @param request
     * @return
     */
    @Override
    public DeleteOrderResponse deleteOrder(DeleteOrderRequest request) {
        DeleteOrderResponse response = new DeleteOrderResponse();
        String orderId = request.getOrderId();
        try {
            request.requestCheck();
            //1.判断order表status >3 时可删除订单
            Order order = orderMapper.selectByPrimaryKey(orderId);
            if (order.getStatus() > 3) {
                orderMapper.deleteByPrimaryKey(orderId);
                //2.删除orderItem表该订单所有对应的商品
                Example example = new Example(OrderItem.class);
                Example.Criteria criteria = example.createCriteria();
                criteria.andEqualTo("orderId", orderId);
                orderItemMapper.deleteByExample(example);
                //3.删除orderShipping表该订单所有对应的寄送信息
                orderShippingMapper.deleteByPrimaryKey(orderId);
                response.setCode(OrderRetCode.SUCCESS.getCode());
                response.setMsg(OrderRetCode.SUCCESS.getMessage());
            }else {
                response.setCode(OrderRetCode.PIPELINE_RUN_EXCEPTION.getCode());
                response.setMsg("订单未完成，不予删除");
            }
        } catch (ValidateException e) {
            response.setCode(e.getErrorCode());
            response.setMsg(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            response.setCode(OrderRetCode.SYSTEM_TIMEOUT.getCode());
            response.setMsg(OrderRetCode.SYSTEM_TIMEOUT.getMessage());
        }

        return response;
    }

	@Autowired
	OrderConverter orderConverter;


	/*
	 * @description: 创建订单
	 * @return: com.mall.order.dto.CreateOrderResponse
	 * @author: mabinbin
	 * @date: 2021/8/25
	 */
	@Override
	public CreateOrderResponse createOrder(CreateOrderRequest request) {
		CreateOrderResponse response = new CreateOrderResponse();
		try {
			//创建pipeline对象（通过工厂的方式来创建），传入请求对象
			TransOutboundInvoker invoker = orderProcessPipelineFactory.build(request);

			//启动pipeline，执行handker方法
			invoker.start(); //启动流程（pipeline来处理）

			//获取处理结果
			AbsTransHandlerContext context = invoker.getContext();

			//把处理结果转换为response
			response = (CreateOrderResponse) context.getConvert().convertCtx2Respond(context);

			//封装状态码
			response.setCode(OrderRetCode.SUCCESS.getCode());
			response.setMsg(OrderRetCode.SUCCESS.getMessage());
		} catch (BizException e) {
			response.setCode(e.getErrorCode());
			response.setMsg(e.getMessage());
		}
		catch (Exception e) {
			response.setCode(OrderRetCode.PIPELINE_RUN_EXCEPTION.getCode());
			response.setMsg(OrderRetCode.PIPELINE_RUN_EXCEPTION.getMessage());
			log.error("OrderCoreServiceImpl.createOrder Occur Exception :" + e);
		}
		return response;
	}

	/*
	 * @description: 订单页面回显
	 * @return: com.mall.order.dto.OrderListResponse
	 * @author: mabinbin
	 * @date: 2021/8/25
	 */
	@Override
	public OrderListResponse showOrder(OrderListRequest orderListRequest) {
		OrderListResponse response = new OrderListResponse();
		//分页
		PageHelper.startPage(orderListRequest.getPage(), orderListRequest.getSize());
		try {
			//通过用户id求订单的个数
			Example orderExample = new Example(Order.class);
			orderExample.setOrderByClause("create_time" + " " + "desc");
			Example.Criteria criteria = orderExample.createCriteria();
			criteria.andEqualTo("userId",orderListRequest.getUserId());
			List<Order> orders = orderMapper.selectByExample(orderExample);
			response.setTotal((long) 0);
			if (!CollectionUtils.isEmpty(orders)) {
				PageInfo<Order> orderPageInfo = new PageInfo<>(orders);
				long total = orderPageInfo.getTotal();
				response.setTotal(total);
			}

			//总的订单
			List<OrderDetailInfo> orderDetailInfos = new ArrayList<>();
			//获得所有订单
			for (Order order : orders) {
				//单个订单
				OrderDetailInfo orderDetailInfo = new OrderDetailInfo();

				//订单信息封装
				BeanUtils.copyProperties(order,orderDetailInfo);

				//订单商品信息封装,通过订单id查商品
				Example orderItemExample = new Example(OrderItem.class);
				orderItemExample.createCriteria().andEqualTo("orderId",order.getOrderId());
				List<OrderItem> orderItems = orderItemMapper.selectByExample(orderItemExample);
				List<OrderItemDto> itemDtos = orderConverter.item2dto(orderItems);
				orderDetailInfo.setOrderItemDto(itemDtos);

				//订单地址封装,通过订单id查地址
				Example orderShippingExample = new Example(OrderShipping.class);
				orderShippingExample.createCriteria().andEqualTo("orderId",order.getOrderId());
				List<OrderShipping> orderShippings = orderShippingMapper.selectByExample(orderShippingExample);
				OrderShipping orderShipping = orderShippings.get(0);
				OrderShippingDto shippingDto = orderConverter.shipping2dto(orderShipping);
				orderDetailInfo.setOrderShippingDto(shippingDto);

				orderDetailInfos.add(orderDetailInfo);
			}
			response.setData(orderDetailInfos);

			//封装状态码
			response.setCode(OrderRetCode.SUCCESS.getCode());
			response.setMsg(OrderRetCode.SUCCESS.getMessage());
		} catch (Exception e) {
			response.setCode(OrderRetCode.SYSTEM_TIMEOUT.getCode());
			response.setMsg(OrderRetCode.SYSTEM_TIMEOUT.getMessage());
			log.error("OrderCoreServiceImpl.showOrder Occur Exception :" + e);
		}
		return response;
	}

	//支付成功时，更新订单状态，更新锁定库存
	@Override
	public PayOrderSuccessResponse payOrderSuccess(PayOrderSuccessRequest request) {

		PayOrderSuccessResponse payOrderSuccessResponse = new PayOrderSuccessResponse();
		String orderId = request.getOrderId();
		try {
			// 2. 修改订单状态，为已支付状态
			Order order = orderMapper.selectByPrimaryKey(orderId);
			order.setStatus(OrderConstants.ORDER_STATUS_PAYED);
			orderMapper.updateByPrimaryKeySelective(order);
			// 3. 修改订单商品条目，对应的库存状态：3 成功扣减库存
			Example example = new Example(OrderItem.class);
			example.createCriteria()
					.andEqualTo("orderId",orderId);
			List<OrderItem> orderItems = orderItemMapper.selectByExample(example);
			for (OrderItem orderItem : orderItems) {
				OrderItem item = new OrderItem();
				item.setId(item.getId());
				item.setStatus(3);
				orderItemMapper.updateByPrimaryKeySelective(item);

				// 4. 修改库存，将订单中商品对应的库存，锁定库存清零
				Long itemId = orderItem.getItemId();
				Integer num = orderItem.getNum();
				Stock stock = stockMapper.selectByPrimaryKey(itemId);
				stock.setLockCount(-num);
				stock.setStockCount((long) 0);
				stockMapper.updateStock(stock);
			}


		} catch (Exception e) {
			log.error("OrderCoreServiceImpl.payOrderSuccess Occur Exception :" + e);
		}

		return payOrderSuccessResponse;
	}

}
